﻿using System.Collections.Generic;

namespace CardGamesLibrary.Cards.Piles
{
    /// <summary>
    /// represents a pile of cards from witch cards can be added or removed.
    /// </summary>
    public abstract class CardPile<TCard> : IList<TCard>, ICardPile<TCard>
        where TCard : Card
    {
        readonly List<TCard> _cards = new List<TCard>();

        public int IndexOf(TCard item)
        {
           return _cards.IndexOf(item);
        }

        public void Insert(int index, TCard item)
        {
            _cards.Insert(index,item);
            NotifyPropertyChanged("Cards");
        }

        public void RemoveAt(int index)
        {
            _cards.RemoveAt(index);
            NotifyPropertyChanged("Cards");
        }

        public TCard this[int index]
        {
            get
            {
                return _cards[index];
            }
            set
            {
                _cards[index] = value;
                NotifyPropertyChanged("Cards");
            }
        }

        public void Add(TCard item)
        {
            if (CanAdd(item))
            {
                _cards.Add(item);
                NotifyPropertyChanged("Cards");
            }
        }

        public abstract bool CanAdd(TCard item);
       

        public void Clear()
        {
            _cards.Clear();
            NotifyPropertyChanged("Cards");
        }

        public bool Contains(TCard item)
        {
           return _cards.Contains(item);
        }

        public void CopyTo(TCard[] array, int arrayIndex)
        {
           _cards.CopyTo(array,arrayIndex);
        }

        public int Count
        {
            get { return _cards.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        public bool Remove(TCard item)
        {
            NotifyPropertyChanged("Cards");
            return _cards.Remove(item);
        }

        public IEnumerator<TCard> GetEnumerator()
        {
            return _cards.GetEnumerator();
        }

        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }

        #region ICardPile<TCard> Members


        public TCard First()
        {
            if (_cards.Count >= 1)
                return _cards[0];
            return null;
        }

        public TCard Last()
        {
            if (_cards.Count >= 1)
                return _cards[_cards.Count-1];
            return null;
        }

        #endregion



        #region INotifyPropertyChanged Members

        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propertyName)
        { 
            if(PropertyChanged != null)
            {
                PropertyChanged(this,new System.ComponentModel.PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }
}
